package etcd

import (
	"context"
	"encoding/json"
	"gitee.com/golang-lib/go-framework/config"
	"github.com/prometheus/common/log"
	"go.etcd.io/etcd/api/v3/mvccpb"
	clientv3 "go.etcd.io/etcd/client/v3"
	"time"
)

var (
	etcdClient *clientv3.Client
)

func InitEtcd(endpoints []string, etcdKey string) (collectConfArr []config.CollectConf, err error) {
	if endpoints == nil || len(endpoints) == 0 {
		log.Debug("no etcd endpoints")
		return
	}

	etcdClient, err := clientv3.New(clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: 5 * time.Second,
	})

	if err != nil {
		log.Error("connect etcd failed, err:", err)
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	cancel()
	resp, err := etcdClient.Get(ctx, etcdKey)
	if err != nil {
		log.Error("client get from etcd failed, err:%v", err)
		return
	}

	log.Info("resp from etcd:%v", resp.Kvs)

	for _, kv := range resp.Kvs {
		if string(kv.Key) == etcdKey {
			err = json.Unmarshal(kv.Value, &collectConfArr)
			if err != nil {
				log.Error("unmarshal failed, err:%v", err)
				continue
			}
			log.Debug("log config is %v", collectConfArr)
		}
	}

	go watchKey(etcdKey)

	return
}

func watchKey(etcdKey string) {
	for {
		watchChan := etcdClient.Watch(context.Background(), etcdKey)
		var collectConf []config.CollectConf
		var getConf = true
		for watchResponse := range watchChan {
			for _, ev := range watchResponse.Events {
				if ev.Type == mvccpb.DELETE {
					log.Warn("key[%s] 's config deleted", etcdKey)
					continue
				}
				if ev.Type == mvccpb.PUT && string(ev.Kv.Key) == etcdKey {
					err := json.Unmarshal(ev.Kv.Value, &collectConf)
					if err != nil {
						log.Error("key [%s], Unmarshal[%s], err:%v ", err)
						getConf = false
						continue
					}
				}
				log.Debug("get config from etcd, %s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
			}
			if getConf {
				log.Debug("get config from etcd succ, %v", collectConf)
				UpdateConfig(collectConf)
			}
		}
	}
}

func UpdateConfig(confs []config.CollectConf) {

}
